//RtpPacket.java

package cn.witsky.rtp2ws.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

class RtpPayloadType 
{
    public static int RTP_PAYLOAD_TYPE_PCMU = 0;
    public static int RTP_PAYLOAD_TYPE_PCMA = 8;
    public static int RTP_PAYLOAD_TYPE_96 = 96;
}

public class RtpPacket
{	
	
	private byte version = 2;

	private byte padding = 0;

	private byte extension = 0;

	private byte csrc_count = 0;

	private byte marker = 1;

	private byte playload_type = 0;

	private int sequence_number = 0;

    private long timestamp = 0;

    private long ssrc = 0;


	public RtpPacket(long ssrcVal) {
		ssrc = ssrcVal;
	}

	public byte[] packet_g711a(byte[] audioData, int audioLen) {

		int rtp_head_len = 12;
		byte[] payload = new byte[rtp_head_len + audioLen];
        
        playload_type = (byte)RtpPayloadType.RTP_PAYLOAD_TYPE_PCMA;
        sequence_number++;
        timestamp +=  audioLen;

		payload[0] = (byte)( (version << 6) +  (padding << 5) + (extension << 4) + csrc_count );
		payload[1] = (byte)( (marker << 7) + playload_type );
	    payload[2] = (byte)( sequence_number / (0xff + 1) );
	    payload[3] = (byte)( sequence_number % (0xff + 1) );
	    payload[4] = (byte)( ( timestamp / (0xffff + 1) ) / (0xff + 1) );
	    payload[5] = (byte)( ( timestamp / (0xffff + 1) ) % (0xff + 1) );
	    payload[6] = (byte)( ( timestamp % (0xffff + 1) ) / (0xff + 1) );
	    payload[7] = (byte)( ( timestamp % (0xffff + 1) ) % (0xff + 1) );
	    payload[8] = (byte)( ( ssrc / (0xffff + 1) ) / (0xff + 1) );
	    payload[9] = (byte)( ( ssrc / (0xffff + 1) ) % (0xff + 1) );
	    payload[10] = (byte)( ( ssrc % (0xffff + 1) ) / (0xff + 1) );
	    payload[11] = (byte)( ( ssrc % (0xffff + 1) ) % (0xff + 1) );

	    System.arraycopy(audioData, 0, payload, rtp_head_len, audioLen);
	    return payload;
	}
	
	public byte[] packet_s16le(byte[] audioData, int audioLen) {

		int rtp_head_len = 12;
		byte[] payload = new byte[rtp_head_len + audioLen];
        
        playload_type = (byte)RtpPayloadType.RTP_PAYLOAD_TYPE_96;
        sequence_number++;
        timestamp +=  audioLen;

		payload[0] = (byte)( (version << 6) +  (padding << 5) + (extension << 4) + csrc_count );
		payload[1] = (byte)( (marker << 7) + playload_type );
	    payload[2] = (byte)( sequence_number / (0xff + 1) );
	    payload[3] = (byte)( sequence_number % (0xff + 1) );
	    payload[4] = (byte)( ( timestamp / (0xffff + 1) ) / (0xff + 1) );
	    payload[5] = (byte)( ( timestamp / (0xffff + 1) ) % (0xff + 1) );
	    payload[6] = (byte)( ( timestamp % (0xffff + 1) ) / (0xff + 1) );
	    payload[7] = (byte)( ( timestamp % (0xffff + 1) ) % (0xff + 1) );
	    payload[8] = (byte)( ( ssrc / (0xffff + 1) ) / (0xff + 1) );
	    payload[9] = (byte)( ( ssrc / (0xffff + 1) ) % (0xff + 1) );
	    payload[10] = (byte)( ( ssrc % (0xffff + 1) ) / (0xff + 1) );
	    payload[11] = (byte)( ( ssrc % (0xffff + 1) ) % (0xff + 1) );

	    System.arraycopy(audioData, 0, payload, rtp_head_len, audioLen);
	    return payload;
	}
	
	public static void  main(String args[]) throws IOException {
		long ssrc = 255;
		int send_interval_ms = 40;
		int audio_need_len = 640;
		int localPort = 56200;
		int peerPort = 29000;
		String peerIP = "192.168.150.39";
		DatagramSocket ds = null;
		InetAddress peerAddress = null;
		InputStream audio_stream = new FileInputStream("C:\\Users\\Admin\\Desktop\\1.pcm");

		try {  
			ds = new DatagramSocket(localPort);
		} catch (SocketException e) {  
            e.printStackTrace();
            System.exit(1);   
        }  

        try {  
            peerAddress = InetAddress.getByName(peerIP);
        } catch (UnknownHostException e) {  
            e.printStackTrace();  
            System.exit(1);   
        }  

		RtpPacket rtp = new RtpPacket(ssrc);
		byte[] audio_data = new byte[audio_need_len]; 

		while (audio_stream.read(audio_data) == audio_need_len) {

		   	byte[] payload = rtp.packet_g711a(audio_data, audio_data.length);
		   	DatagramPacket dp = new DatagramPacket(payload, payload.length, peerAddress, peerPort);
            ds.send(dp); 
			//System.out.println(Arrays.toString(payload));
			try {
				Thread.sleep(send_interval_ms);

			} catch (InterruptedException e) {
				e.printStackTrace();
				break;
			}
		}
		ds.close();
	}
}
